package com.functest.orm

import groovy.sql.Sql

import java.text.SimpleDateFormat

/**
 * Created with IntelliJ IDEA.
 * User: KovalevAS
 * Date: 29.07.13
 * Time: 15:14
 * To change this template use File | Settings | File Templates.
 */
class Simple {
    static {
        Class.forName('org.sqlite.JDBC');
    }
    final static Sql ourDB

    static class FullClass {
        int id
        int same_name_field
        int diff_name_field
        String one_to_many_calculated_field /*glue of same_name_field and diff_name_field*/
        String full_calculated_field

/* Default constructor, required by Provider */
        FullClass(Map params) {
            for (Map.Entry entry in params.entrySet()) {
                if (entry.value != null) {
                    this."${entry.key }" = entry.value
                }
            }
        }
    }

    /*SingleDbTableMappers*/
    static SingleDbTableMapper<FullClass> same_name_field_mapper
    static SingleDbTableMapper<FullClass> diff_name_field_mapper
    static SingleDbTableMapper<FullClass> one_to_many_field_mapper
    static SingleDbTableMapper<FullClass> full_calculated_field_mapper
    /*MultiTableMappers*/
    static MultiTableMapper<FullClass> multitable_mapper
    /* Provider */
    static BaseProvider<FullClass> provider


    static {
        ourDB = Sql.newInstance('jdbc:sqlite::memory:', 'org.sqlite.SQLite')
        Simple.ourDB.with {
            execute("create table same_name_field_table (id int, same_name_field int)")
            execute("insert into same_name_field_table values (1, 42)")
            execute("insert into same_name_field_table values (2, null)")
            execute("insert into same_name_field_table values (3, null)")
            execute("insert into same_name_field_table values (4, 666)")

            execute("create table diff_name_field_table (id int, different_name_field int)")
            execute("insert into same_name_field_table values (1, 42)")
            execute("insert into diff_name_field_table values (2, 42)")
            execute("insert into diff_name_field_table values (3, null)")
            execute("insert into same_name_field_table values (4, 666)")

            execute("create table one_to_many_calculated_field_table (id int, first_field int, second_field int)")
            execute("insert into one_to_many_calculated_field_table values (1, 42, 24)")
            execute("insert into one_to_many_calculated_field_table values (4, 666, 777)")

            execute("create table full_calculated_field_table (id int)")
            execute("insert into full_calculated_field_table values (1)")
            execute("insert into full_calculated_field_table values (2)")
            execute("insert into full_calculated_field_table values (3)")
            execute("insert into full_calculated_field_table values (4)")
        }

        same_name_field_mapper = new SingleDbTableMapper<FullClass>(
                new MapperFields().with {
                    field('id')
                    field('same_name_field')
                    delegate as MapperFields
                }
                , { Simple.ourDB }
                , 'same_name_field_table'
                , 'id'
                , FullClass
        )

        diff_name_field_mapper = new SingleDbTableMapper<FullClass>(
                new MapperFields().with {
                    field('id')
                    field('diff_name_field', 'different_name_field')
                    delegate as MapperFields
                }
                , { Simple.ourDB }
                , 'diff_name_field_table'
                , 'id'
                , FullClass
        )

        one_to_many_field_mapper = new SingleDbTableMapper<FullClass>(
                new MapperFields().with {
                    field('id')
                    field('one_to_many_calculated_field', ['first_field', 'second_field'],
                            {
                                Field f, Map m ->
                                    ((m['first_field'].toString()) + '_' +
                                            (m['second_field'].toString()))
                            } as Closure,
                            {
                                Field f, def value ->
                                    def split_list = (value as String).split('_')
                                    [first: split_list.first(), second: split_list.last()]
                            } as Closure
                    )
                    delegate as MapperFields
                }
                , { Simple.ourDB }
                , 'one_to_many_calculated_field_table'
                , 'id'
                , FullClass
        )

        full_calculated_field_mapper = new SingleDbTableMapper<FullClass>(
                new MapperFields().with {
                    field('id')
                    field('full_calculated_field', [], { Field f, Map m ->
                        def date = new Date()
                        def sdf = new SimpleDateFormat("MM/dd/yyyy")
                        sdf.format(date)
                    } as Closure,
                            { Field f, def value ->
                                [today: Date.parse("MM/dd/yyyy", value as String)]
                            } as Closure)
                    delegate as MapperFields
                }
                , { TestData.ourDB }
                , 'full_calculated_field_table'
                , 'id'
                , FullClass
        )

        multitable_mapper = new MultiTableMapper<FullClass>(
                [same_name_field_mapper, diff_name_field_mapper, one_to_many_field_mapper, full_calculated_field_mapper]
                , FullClass
                , []
        )

        provider = new BaseProvider<FullClass>(FullClass, multitable_mapper)
    }
}
